package com.linshidream.intrachat.simplenio.pipeline;

import com.linshidream.intrachat.simplenio.pipeline.context.MiniHandlerContext;
import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelInboundHandler;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * Created on 2025/8/19 18:21
 *
 * @author linshidream
 * @version 1.0.0
 * @description
 */

public class LengthFieldMessageDecoder implements MiniChannelInboundHandler {

    /**
     * 4 bytes表示消息长度（int）
     */
    private static final int LENGTH_HEADER_SIZE = 4;

    @Override
    public void channelRead(MiniHandlerContext ctx, Object msg) {
        // 该编码器只处理 ByteBuffer 对象
        if (!(msg instanceof ByteBuffer)) {
            ctx.fireChannelRead(msg);
            return;
        }

        System.out.println("[" + ctx.handlerName() + "],从通道读数据");

        ByteBuffer buffer = (ByteBuffer) msg;
        buffer.flip();

        List<String> messages = new ArrayList<>();

        while (buffer.remaining() > LENGTH_HEADER_SIZE) {
            // 标记下当前的位置
            buffer.mark();
            // 获取到4kb(int)
            int len = buffer.getInt();
            if (buffer.remaining() < len) {
                buffer.reset();
                break;
            }

            // 每次读一定长度的数据。
            byte[] msgBytes = new byte[len];
            buffer.get(msgBytes);
            messages.add(new String(msgBytes, StandardCharsets.UTF_8));
        }

        // 保留未读 开启写模式
        buffer.compact();

        // 读事件传继续传递
        for (String s : messages) {
            ctx.fireChannelRead(s);
        }
    }
}
